package light.head.framework.interceptor;

import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import light.head.cache.Cache;
import light.head.constant.Msg;
import light.head.constant.Parm;
import light.head.constant.Sys;
import light.head.constant.Url;
import light.head.dao.sys.OrganTypeHandleDAO;
import light.head.dao.sys.RoleHandleDAO;
import light.head.model.Log;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * @author janhang
 * @2010-12-13 下午12:51:16
 */
public class SupporterInterceptor extends HandlerInterceptorAdapter {
	
	private OrganTypeHandleDAO othDAO;
	private RoleHandleDAO rhDAO;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		
		if (null == handler) {
			request.setAttribute(Sys.INFO, Msg.PERMISSION_DENIED);
			request.getRequestDispatcher(Msg.ERROR).forward(request, response);
			return false;
		}

		HttpSession session = request.getSession();
		
		String email = (String)session.getAttribute(Parm.CU_EMAIL);
		Integer roleCode = (Integer)session.getAttribute(Parm.CU_ROLE_CODE);
		Boolean isManager = (Boolean)session.getAttribute(Parm.CU_IS_MANAGER);
		Integer organTypeCode = (Integer)session.getAttribute(Parm.CU_ORGAN_TYPE_CODE);
		
		// 如果只超级管理员，就直接返回true
		if (Sys.ADMIN.equals(email))
			return true;
		
		// 获取操作编号
		String handleCode = getHandleCode(request);

		// 判断操作是否需要控制权限
		if (!isValidate(handleCode))
			return true;
		
		// 获取角色code，如果为null说明是非法访问直接跳转到登陆页面
		if (null == roleCode && (null == isManager || !isManager)) {
			request.setAttribute(Parm.INFO, Msg.NO_LOGIN);
			request.getRequestDispatcher(Url.LOGINOUT_DO).forward(request, response);
			return false;
		}

		// 判断当前用户的角色是否具备这个操作的权限，不具备就跳转到登陆页面
		Map<String, Boolean> handleMap = null;
		if (null != isManager && isManager)
			handleMap = othDAO.getHandleMapByOrganTypeCode(organTypeCode);
		else 
			handleMap = rhDAO.getHandleMapByRoleCode(roleCode);
		
		if ((null == handleMap || null == handleMap.get(handleCode)) && !Sys.ADMIN.equals(email)) {
			request.setAttribute(Parm.INFO, Msg.NO_LOGIN);
			request.getRequestDispatcher(Url.LOGINOUT_DO).forward(request, response);
			return false;
		}
		
		return true;
	}
	
	private String getHandleCode(HttpServletRequest request) {
		String ruri = request.getRequestURI();
		ruri = ruri.substring(ruri.indexOf("/m/") + 3, ruri.length());
		
		
		int sub = ruri.indexOf('/') != -1 ? ruri.indexOf('/') : ruri.length();
		String url = ruri.substring(0, sub);
		
		if (sub != ruri.length())
			url = url + "-" + ruri.substring(sub + 1, (ruri.indexOf('?') != -1 ? ruri.indexOf('?') : ruri.length()));
			
		if (url.indexOf('.') != -1)
			url = url.substring(0, url.indexOf('.'));
		return url;
	}
	
	/**
	 * 判断当前请求是否需要验证权限
	 * @return	true 要验证 / false 不验证
	 */
	private boolean isValidate(String url) {
		return null != Cache.handleMap.get(url) ? true : false;
	}
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		String handleCode = getHandleCode(request);
		
		// 判断系统配置中是否需要记录日志
		if (null != Cache.handleMap.get(handleCode) && Cache.handleMap.get(handleCode)) {
			HttpSession session = request.getSession();
			
			Integer cu_code = (Integer)session.getAttribute(Parm.CU_CODE);
			String itemCode = request.getParameter(Parm.CODE);
			Log log = new Log();
			log.setHc(handleCode);
			log.setCu(cu_code);
			log.setCt(new Date());
			if (null != itemCode && !"".equals(itemCode))
				log.setIc(Integer.parseInt(itemCode));
			
			rhDAO.add(log);
		}
	}

	@Autowired
	public void setOthDAO(OrganTypeHandleDAO othDAO) {
		this.othDAO = othDAO;
	}
	@Autowired
	public void setRhDAO(RoleHandleDAO rhDAO) {
		this.rhDAO = rhDAO;
	}
	
}
